/**
* Class to contain the declared and implemented interfaces for a plugin component
*/
jsx3.lang.Class.defineClass("ux.core.util.component.PluginInterfaces",
        jsx3.lang.Object,
        null,
        function(config) {

            /**
             * {jsx3.util.List} List of {ux.core.util.component.DeclaredInterface} objects representing interfaces
             * declared by this component
             * @private
             */
            config.prototype.declaredInterfaces = null;

            /**
             * {jsx3.util.List} List of {ux.core.util.component.ImplementedInterface} objects representing interfaces
             * implemented by this component
             * @private
             */
            config.prototype.implementedInterfaces = null;

            /**
             * Constructor for this class.
             *
             * @param entity {jsx3.xml.Entity} an xml node containing the information for a declared and implemented interfaces for this component
             * @throws {ux.core.exception.InvalidComponentSchemaException} if the xml is invalid
             */
            config.prototype.init = function(entity) {
                this.jsxsuper();
                this.declaredInterfaces = new jsx3.util.List(0);
                this.implementedInterfaces = new jsx3.util.List(0);
                var children = entity.getChildNodes().iterator();
                while(children.hasNext()) {
                    var child = children.next();
                    var childName = child.getNodeName();
                    if(childName == "declared_interfaces") {
                        var childDecs = child.getChildNodes().iterator();
                        while(childDecs.hasNext()) {
                            var childDec = childDecs.next();
                            var childDecName = childDec.getNodeName();
                            if(childDecName == "decl_interface") {
                                this.declaredInterfaces.add(new ux.core.util.component.DeclaredInterface(childDec),this.declaredInterfaces.size());
                            }
                            else {
                                throw new ux.core.exception.InvalidComponentSchemaException("Unknown tag '" + childDecName + "' in the 'declared_interfaces' tag of the component schema.  Supported tags are: decl_interface");
                            }
                        }
                        if(this.declaredInterfaces.size() == 0) {
                            throw new ux.core.exception.InvalidComponentSchemaException("Tag 'declared_interfaces' requires at least one 'decl_interface' child tag.")
                        }
                    }
                    else if(childName == "implemented_interfaces") {
                        var childImps = child.getChildNodes().iterator();
                        while(childImps.hasNext()) {
                            var childImp = childImps.next();
                            var childImpName = childImp.getNodeName();
                            if(childImpName == "impl_interface") {
                                this.implementedInterfaces.add(new ux.core.util.component.ImplementedInterface(childImp),this.implementedInterfaces.size());
                            }
                            else {
                                throw new ux.core.exception.InvalidComponentSchemaException("Unknown tag '" + childImpName + "' in the 'implemented_interfaces' tag of the component schema.  Supported tags are: impl_interface");
                            }
                        }
                        if(this.implementedInterfaces.size() == 0) {
                            throw new ux.core.exception.InvalidComponentSchemaException("Tag 'implemented_interfaces' requires at least one 'impl_interface' child tag.")
                        }
                    }
                    else {
                        throw new ux.core.exception.InvalidComponentSchemaException("Unknown tag '" + childName + "' in the 'interfaces' tag of the component schema.  Supported tags are: declared_interfaces, implemented_interfaces");
                    }
                }
                if((this.declaredInterfaces.size() == 0) && (this.implementedInterfaces.size() == 0)) {
                    throw new ux.core.exception.InvalidComponentSchemaException("Tag 'interfaces' requires at least one of the following child tags: declared_interfaces, implemented_interfaces")
                }
            }

            /**
            * Returns an iterator of the declared plugin interfaces for this plugin container.  If empty, this component is NOT
            * a plugin container.
            *
            * @returns {jsx3.util.Iterator} an iterator of the declared plugin interfaces {ux.core.util.component.DeclaredInterface}
            *          for this plugin container.
            */
            config.prototype.getDeclaredInterfaces = function() {
                return this.declaredInterfaces.clone().iterator();
            }

            /**
            * Returns an iterator of the implemented plugin interfaces for this plugin component.  If empty, this component is NOT
            * a plugin component.
            *
            * @returns {jsx3.util.Iterator} an iterator of the implemented plugin interfaces {ux.core.util.component.ImplementedInterface}
            *          for this plugin component.
            */
            config.prototype.getImplementedInterfaces = function() {
                return this.implementedInterfaces.clone().iterator();
            }

            /**
            * Returns a string representing this object in the xml format specified by the component.xsd schema
            *
            * @param prepend {String} a string to be prepended to each line of the returned XML (useful for indenting)
            *
            * @returns {String} this Resources object as XML, as specified by the component.xsd schema
            */
            config.prototype.toString = function(prepend) {
                if(!prepend) {
                    prepend = "";
                }
                var ret = prepend + "<interfaces>\n";
                if(this.declaredInterfaces.size() > 0) {
                    ret += prepend + "   <declared_interfaces>\n";
                    var iter = this.declaredInterfaces.iterator();
                    while(iter.hasNext()) {
                        ret += iter.next().toString(prepend + "      ");
                    }
                    ret += prepend + "   </declared_interfaces>\n";
                }
                if(this.implementedInterfaces.size() > 0) {
                    ret += prepend + "   <implemented_interfaces>\n";
                    var iter = this.implementedInterfaces.iterator();
                    while(iter.hasNext()) {
                        ret += iter.next().toString(prepend + "      ");
                    }
                    ret += prepend + "   </implemented_interfaces>\n";
                }
                ret += prepend + "</interfaces>\n";
                return ret;
            }
        }
);